// jXHR.js (JSON-P XHR)
// v0.1 (c) Kyle Simpson
// License: MIT
// modified by gueron Jonathan to work with strophe lib
// for http://www.iadvize.com

(function(global){
    var SETTIMEOUT = global.setTimeout, // for better compression
        doc = global.document,
        callback_counter = 0;

    global.jXHR = function() {
        var script_url,
            script_loaded,
            jsonp_callback,
            scriptElem,
            publicAPI = null;

        function removeScript() { try { scriptElem.parentNode.removeChild(scriptElem); } catch (err) { } }

        function reset() {
            script_loaded = false;
            script_url = "";
            removeScript();
            scriptElem = null;
            fireReadyStateChange(0);
        }

        function ThrowError(msg) {
            try {
                publicAPI.onerror.call(publicAPI,msg,script_url);
            } catch (err) {
                //throw new Error(msg);
            }
        }

        function handleScriptLoad() {
            if ((this.readyState && this.readyState!=="complete" && this.readyState!=="loaded") || script_loaded) { return; }
            this.onload = this.onreadystatechange = null; // prevent memory leak
            script_loaded = true;
            if (publicAPI.readyState !== 4) ThrowError("handleScriptLoad: Script failed to load ["+script_url+"].");
            removeScript();
        }

        function parseXMLString(xmlStr) {
            var xmlDoc = null;
            if(window.DOMParser) {
                var parser = new DOMParser();
                xmlDoc = parser.parseFromString(xmlStr,"text/xml");
            }
            else {
                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
                xmlDoc.async="false";
                xmlDoc.loadXML(xmlStr);
            }
            return xmlDoc;
        }

        function fireReadyStateChange(rs,args) {

            args = args || [];
            publicAPI.readyState = rs;
            if (rs == 4) {
                publicAPI.responseText = args[0].reply;
                publicAPI.responseXML = parseXMLString(args[0].reply);
            }
            if (typeof publicAPI.onreadystatechange === "function") publicAPI.onreadystatechange.apply(publicAPI,args);
        }

        publicAPI = {
            onerror:null,
            onreadystatechange:null,
            readyState:0,
            status:200,
            responseBody: null,
            responseText: null,
            responseXML: null,
            open:function(method,url){
                reset();
                var internal_callback = "cb"+(callback_counter++);
                (function(icb){
                    global.jXHR[icb] = function() {
                        try { fireReadyStateChange.call(publicAPI,4,arguments); }
                        catch(err) {
                            publicAPI.readyState = -1;
                            ThrowError("Script failed to run ["+script_url+"].");
                        }
                        global.jXHR[icb] = null;
                    };
                })(internal_callback);
                script_url = url + '?callback=?jXHR&data=';
                script_url = script_url.replace(/=\?jXHR/,"=jXHR."+internal_callback);
                fireReadyStateChange(1);
            },
            send:function(data){
                script_url = script_url + encodeURIComponent(data);
                SETTIMEOUT(function(){
                    scriptElem = doc.createElement("script");
                    scriptElem.setAttribute("type","text/javascript");
                    scriptElem.onload = scriptElem.onreadystatechange = function(){handleScriptLoad.call(scriptElem);};
                    scriptElem.setAttribute("src",script_url);
                    doc.getElementsByTagName("head")[0].appendChild(scriptElem);
                },0);
                fireReadyStateChange(2);
            },
            abort:function(){},
            setRequestHeader:function(){}, // noop
            getResponseHeader:function(){return "";}, // basically noop
            getAllResponseHeaders:function(){return [];} // ditto
        };

        reset();

        return publicAPI;
    };
})(window);
